package com.cm367.teamc;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;

import com.cm367.teamc.bean.Leave;
import com.cm367.teamc.calendar.CalendarViewStaff;
import com.cm367.teamc.dao.PublicHolidayDAO;
import com.cm367.teamc.message.EMessage;
import com.cm367.teamc.service.LeaveRulesService;
import com.cm367.teamc.service.LeaveService;
import com.cm367.teamc.session.UserSession;
import com.cm367.teamc.util.DateUtil;

@ManagedBean
public class LeaveRequest {
	private String leaveID;
	private String userID;
	private Date dateFrom;
	private Date dateTo;
	private int days;
	private String reason;
	private String status;
	private String leaveType;
	private int year;

	private String result;

	private Date selectDate;

	@ManagedProperty(value = "#{eMessage}")
	private EMessage eMessage;

	@ManagedProperty(value = "#{userSession}")
	private UserSession userSession;

	@ManagedProperty(value = "#{publicHolidayDAO}")
	private PublicHolidayDAO publicHolidayDAO;

	@ManagedProperty(value = "#{leaveRulesService}")
	private LeaveRulesService leaveRulesService;

	@ManagedProperty(value = "#{leaveService}")
	private LeaveService leaveService;

	@ManagedProperty(value = "#{calendarViewStaff}")
	private CalendarViewStaff calendarViewStaff;

	public LeaveRequest() {
		Calendar c = Calendar.getInstance();
		year = c.get(Calendar.YEAR);
	}

	public LeaveRulesService getLeaveRulesService() {
		return leaveRulesService;
	}

	public void setLeaveRulesService(LeaveRulesService leaveRulesService) {
		this.leaveRulesService = leaveRulesService;
	}

	public PublicHolidayDAO getPublicHolidayDAO() {
		return publicHolidayDAO;
	}

	public void setPublicHolidayDAO(PublicHolidayDAO publicHolidayDAO) {
		this.publicHolidayDAO = publicHolidayDAO;
	}

	public String getLeaveID() {
		return leaveID;
	}

	public void setLeaveID(String leaveID) {
		this.leaveID = leaveID;
	}

	public String getUserID() {
		return userSession.getUserID();
	}

	public void setUserID(String userID) {
		this.userID = userID;
	}

	public Date getDateFrom() {
		return dateFrom;
	}

	public void setDateFrom(Date dateFrom) {
		this.dateFrom = dateFrom;
	}

	public Date getDateTo() {
		return dateTo;
	}

	public void setDateTo(Date dateTo) {
		this.dateTo = dateTo;
	}

	public int getDays() {
		return days;
	}

	public void setDays(int days) {
		this.days = days;
	}

	public String getReason() {
		return reason;
	}

	public void setReason(String reason) {
		this.reason = reason;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public String getLeaveType() {
		return leaveType;
	}

	public void setLeaveType(String leaveType) {
		this.leaveType = leaveType;
	}

	public EMessage geteMessage() {
		return eMessage;
	}

	public void seteMessage(EMessage eMessage) {
		this.eMessage = eMessage;
	}

	public UserSession getUserSession() {
		return userSession;
	}

	public void setUserSession(UserSession userSession) {
		this.userSession = userSession;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	public CalendarViewStaff getCalendarViewStaff() {
		return calendarViewStaff;
	}

	public void setCalendarViewStaff(CalendarViewStaff calendarViewStaff) {
		this.calendarViewStaff = calendarViewStaff;
	}

	@SuppressWarnings("deprecation")
	public void countdays() throws SQLException {
		if (dateTo != null && dateFrom != null)
			days = ((int) ((dateTo.getTime() - dateFrom.getTime()) / (1000 * 3600 * 24))) + 1;
		Date date = new Date(dateFrom.getTime());
		int loop = days;
		List<String> publicHoildays = publicHolidayDAO.getPublicHoliday();
		for (int i = 1; i <= loop; i++) {
			if (date.getDay() == 0 || date.getDay() == 6
					|| publicHoildays.contains(DateUtil.getStringDate(date)))
				days = days - 1;
			date.setDate(date.getDate() + 1);// next day
		}
	}

	public LeaveService getLeaveService() {
		return leaveService;
	}

	public void setLeaveService(LeaveService leaveService) {
		this.leaveService = leaveService;
	}

	public List<LeaveRequest> getLeaveHistory() {
		List<LeaveRequest> list = new ArrayList<LeaveRequest>();
		List<String> types = leaveRulesService.getTypes();
		for (String type : types) {
			list.addAll(leaveService.getLeaveHistory(userSession.getUserID(),
					type));
		}
		return list;
	}

	public List<Leave> getLeaves() {
		List<Leave> list = new ArrayList<Leave>();
		List<String> types = leaveRulesService.getTypes();
		for (String type : types) {
			list.addAll(leaveService.getLeave(userSession.getUserID(), type,
					year + "-01-01", year + "-12-31"));
		}
		return list;
	}

	public List<Leave> getAllLeaves() {
		List<Leave> list = new ArrayList<Leave>();
		if (selectDate != null) {
			String date = DateUtil.getStringDate(selectDate);
			String type = calendarViewStaff.getType();
			list.addAll(leaveService.getAllLeave(userSession.getUserID(), type,
					date, date));
		}
		return list;
	}

	public String getLeft() {
		String result = "";
		List<String> types = leaveRulesService.getTypes();
		result += year + eMessage.leaveStaus();
		for (String type : types) {
			int day = leaveRulesService.getLeft(userSession.getUserID(), type,
					year);
			int pendingDay = leaveRulesService.getPending(
					userSession.getUserID(), type, year);
			int approvedDay = leaveRulesService.getApproved(
					userSession.getUserID(), type, year);
			result += eMessage.typeLeft(type, day);
			result += eMessage.pendingCount(pendingDay);
			result += eMessage.approveCount(approvedDay);
		}
		return result;
	}

	public String leaveAction() {
		FacesContext fc = FacesContext.getCurrentInstance();
		Map<String, String> params = fc.getExternalContext()
				.getRequestParameterMap();
		int type = Integer.parseInt(params.get("type"));
		int leaveID = Integer.parseInt(params.get("LID"));
		switch (type) {
		case 1:
			leaveService.changeStatus("Cancelled", leaveID);
			break;
		case 3:
			leaveService.changeStatus("Cancel Leave", leaveID);
			break;
		case 5:
			leaveService.changeStatus("Approved", leaveID);
			break;
		}
		return null;
	}

	public String req() {
		try {
			countdays();
			if (days <= 0) {
				result = eMessage.peroidError();
				return null;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		result = leaveService.createLeave(userSession.getUserID(),
				DateUtil.getStringDate(dateFrom),
				DateUtil.getStringDate(dateTo), days, reason, leaveType);
		if (result.equals("1")) {
			result = eMessage.createError();
		} else if (result.equals("2")) {
			result = eMessage.notEnough();
		} else {
			result = eMessage.leaveSuccess();
		}
		return null;
	}

	public Date getSelectDate() {
		return selectDate;
	}

	public void setSelectDate(Date selectDate) {
		this.selectDate = selectDate;
	}

}
